// 组件
import React, { Component } from 'react'
import Taro, { Config } from '@tarojs/taro'
import { View, Button, Text, Image } from '@tarojs/components'
import { AtIcon, AtInput } from 'taro-ui'
// 功能函数
import { connect } from 'react-redux'
import addUserInfo from '@/actions/userInfo'
import { UserInfoData } from '@/constants/userInfo'
import api from '@/services/config/index'
import md5 from 'js-md5/build/md5.min.js'
import { JudgingMobile, JudgingPwd } from '@/utils/common'
// 静态资源
import './index.scss'

// #region 书写注意
//
// 目前 typescript 版本还无法在装饰器模式下将 Props 注入到 Taro.Component 中的 props 属性
// 需要显示声明 connect 的参数类型并通过 interface 的方式指定 Taro.Component 子类的 props
// 这样才能完成类型检查和 IDE 的自动提示
// 使用函数模式则无此限制
// ref: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/20796
//
// #endregion
// type 和 interface都可以描述一个对象或函数，type 可以声明基本类型别名，联合类型，元组等类型，interface 能够声明合并

// 定义props的值
type PageStateProps = {}

// 定义props里的dispatch函数
type PageDispatchProps = {
  onAddLogin: (data: UserInfoData) => void
}

type PageOwnProps = {}

// 定义当前组件的state
type PageState = {
  account: string
  password: string
  accountError: boolean
  passwordError: boolean
}

type IProps = PageStateProps & PageDispatchProps & PageOwnProps

// 声明合并，接口类声明合并
interface Login {
  props: IProps
}

@connect(
  () => {
    return {}
  },
  (dispatch) => {
    return {
      onAddLogin(data: UserInfoData) {
        dispatch(addUserInfo(data))
      }
    }
  }
)
class Login extends Component<PageOwnProps, PageState> {
  /**
   * 指定config的类型声明为: Taro.Config
   *
   * 由于 typescript 对于 object 类型推导只能推出 Key 的基本类型
   * 对于像 navigationBarTextStyle: 'black' 这样的推导出的类型是 string
   * 提示和声明 navigationBarTextStyle: 'black' | 'white' 类型冲突, 需要显示声明类型
   */

  state: PageState = {
    account: '',
    password: '',
    accountError: false,
    passwordError: false
  }
  componentDidMount() {
    const token = Taro.getStorageSync('token')
    if (token) {
      Taro.switchTab({
        url: '/pages/My/index'
      })
    }
  }
  componentWillReceiveProps() {}
  config: Config = {
    navigationBarTitleText: '登录'
  }

  componentDidShow() {}

  componentDidHide() {}

  getAccount(value: string) {
    this.setState({ account: value })
  }
  getpassword(value: string) {
    this.setState({ password: value })
  }

  // 表单验证
  formValidation(account: string, password: string) {
    const handleStep = [
      {
        judgeKey: !JudgingMobile(account),
        judgeAdopt: () => {
          this.setState({ accountError: true })
        },
        judgeFail: () => {
          this.setState({ accountError: false })
        }
      },
      {
        judgeKey: !JudgingPwd(password),
        judgeAdopt: () => {
          this.setState({ passwordError: true })
        },
        judgeFail: () => {
          this.setState({ passwordError: false })
        }
      }
    ]
    return handleStep
  }
  // 登录
  hanleLogin() {
    const { account, password } = this.state
    let flag = false
    const formValidation = this.formValidation(account, password)
    formValidation.forEach((item) => {
      if (item.judgeKey) {
        item.judgeAdopt.call(this)
        flag = true
      } else {
        item.judgeFail.call(this)
      }
    })
    if (flag) {
      Taro.showToast({
        title: '账号或密码错误！',
        icon: 'none'
      })
      return
    }
    this.setState({ accountError: false, passwordError: false })
    const param = {
      mobile: account,
      password: md5(password)
    }
    api['user/login'](param).then((res) => {
      Taro.showToast({
        title: '登录成功',
        icon: 'none'
      })
      const data = res.data[0]
      this.props.onAddLogin(data)
      Taro.setStorageSync('userInfo', JSON.stringify(data))
      Taro.setStorageSync('token', data.log_verify_code)
      Taro.switchTab({
        url: '/pages/Index/index'
      })
    })
  }
  // 微信登录
  wxLogin() {
    Taro.login({
      success: function(res) {
        console.log(res)
        // 获临时登录凭证code，传给服务端
        Taro.showToast({
          title: '登录中',
          icon: 'none',
          duration: 2000
        })
      }
    })
  }
  render() {
    const { account, password, accountError, passwordError } = this.state
    return (
      <View className='login'>
        <Image
          src={require('@/assets/img/login/login_img.png').default}
          className='logon-figure'
        ></Image>
        <View className='login-title'>和谐共享社区</View>
        {/* 输入账号和密码登录 */}
        <View className='login-user'>
          <AtIcon prefixClass='icon' value='sjh' size='28' color='#fd4344'></AtIcon>
          <AtInput
            name='value1'
            type='phone'
            placeholder='请输入手机号'
            value={account}
            onChange={this.getAccount.bind(this)}
            className='input'
            border={false}
            error={accountError}
            placeholderClass='inpur-placeholder'
          ></AtInput>
        </View>
        <View className='login-password'>
          <AtIcon prefixClass='icon' value='password' size='28' color='#fd4344'></AtIcon>
          <AtInput
            name='value2'
            type='password'
            password
            placeholder='请输入6-16位的数字、字母'
            value={password}
            onChange={this.getpassword.bind(this)}
            className='input'
            border={false}
            placeholderClass='inpur-placeholder'
            error={passwordError}
          ></AtInput>
        </View>
        {/* 忘记密码和注册 */}
        <View className='login-other'>
          <Text
            className='login-other--password'
            onClick={() => {
              Taro.navigateTo({
                url: '/pages/RetrievePwd/index'
              })
            }}
          >
            忘记密码？
          </Text>
          <Text
            className='login-other--register'
            onClick={() => {
              Taro.navigateTo({
                url: '/pages/Register/index'
              })
            }}
          >
            立即注册
          </Text>
        </View>
        <Button className='login-btn' size='mini' onClick={this.hanleLogin.bind(this)}>
          登录
        </Button>
        <View className='login-otherTips'>
          <View className='login-otherTip-main'>
            <View className='line-left'></View>
            <Text className='login-otherTips--text'>其他方式</Text>
            <View className='line-right'></View>
          </View>
        </View>
        {/* 其他登录方式 */}
        <View className='login-otherLogin'>
          <Image
            src={require('@/assets/img/login/login_bgimg.png').default}
            className='login-otherLogin--img'
          ></Image>
          <View onClick={this.wxLogin.bind(this)}>
            <Image
              src={require('@/assets/img/login/wxlogin.png').default}
              className='login-wx'
            ></Image>
          </View>
        </View>
      </View>
    )
  }
}

// #region 导出注意
//
// 经过上面的声明后需要将导出的 Taro.Component 子类修改为子类本身的 props 属性
// 这样在使用这个子类时 Ts 才不会提示缺少 JSX 类型参数错误
//
// #endregion

export default Login
